package cn.waters321.rock.generator.core;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.xiaoleilu.hutool.date.DateUtil;
import cn.waters321.rock.generator.config.BaseInfo;
import cn.waters321.rock.generator.config.BusinessInfo;
import cn.waters321.rock.generator.config.FrameInfo;
import cn.waters321.rock.generator.config.GeneratorConfig;

public class CustomDaoGenerator {

  GeneratorConfig generatorConfig = new GeneratorConfig();

  private BaseInfo baseInfo;
  private String name;

  public CustomDaoGenerator(String moudle, String name) {
    this.name = name;

    generatorConfig
        .setEntityPackageName(generatorConfig.getEntityPackageName().replace("{moudle}", moudle));
    generatorConfig
        .setDaoPackageName(generatorConfig.getDaoPackageName().replace("{moudle}", moudle));
    generatorConfig
        .setServicePackageName(generatorConfig.getServicePackageName().replace("{moudle}", moudle));
    generatorConfig.setServiceImplPackageName(
        generatorConfig.getServiceImplPackageName().replace("{moudle}", moudle));

    generatorConfig.setCustomDaoPackageName(
        generatorConfig.getCustomDaoPackageName().replace("{moudle}", moudle));
    generatorConfig.setCustomMapperPackageName(
        generatorConfig.getCustomMapperPackageName().replace("{moudle}", moudle));
    generatorConfig.setCustomServicePackageName(
        generatorConfig.getCustomServicePackageName().replace("{moudle}", moudle));
    generatorConfig.setCustomServiceImplPackageName(
        generatorConfig.getCustomServiceImplPackageName().replace("{moudle}", moudle));

    if ("frame".equals(moudle)) {
      baseInfo = new FrameInfo();
    } else if ("business".equals(moudle)) {
      baseInfo = new BusinessInfo();
    }
  }

  // 全局配置
  public void golbalConfig(AutoGenerator mpg) {

    InetAddress localHost = null;
    try {
      localHost = InetAddress.getLocalHost();
    } catch (UnknownHostException e) {
      e.printStackTrace();
    }
    String hostAddress = localHost.getHostAddress();
    String hostName = localHost.getHostName();

    mpg.setGlobalConfig(new GlobalConfig()
        .setOutputDir(GeneratorConfig.OUTPUT_ROOT + generatorConfig.getCustomDaoPath())// 输出目录
        .setFileOverride(true)// 是否覆盖文件
        .setActiveRecord(true)// 开启 activeRecord 模式
        .setEnableCache(false)// XML 二级缓存
        .setBaseResultMap(false)// XML ResultMap
        .setBaseColumnList(false)// XML columList
        .setMapperName(name + "CustomDao").setXmlName(name + "QueryMapper")// DAO名称
        .setAuthor(hostName + ":" + hostAddress + ":" + DateUtil.now()).setOpen(false));
  }

  // 数据源配置
  public void dataSource(AutoGenerator mpg) {
    mpg.setDataSource(new DataSourceConfig().setDbType(baseInfo.getDbTypeEnum())
        .setDriverName(baseInfo.getDriverName()).setUsername(baseInfo.getUserName())
        .setPassword(baseInfo.getPassword()).setUrl(baseInfo.getUrl()));
  }

  // 策略配置
  public void strategyConfig(AutoGenerator mpg) {
    mpg.setStrategy(new StrategyConfig().setNaming(NamingStrategy.underline_to_camel)// 表名生成策略
        .setInclude(
            baseInfo.getExcludeTables().toArray(new String[baseInfo.getExcludeTables().size()])));
  }

  // 包配置
  public void packageInfo(AutoGenerator mpg) {
    mpg.setPackageInfo(
        // 包配置
        new PackageConfig().setParent(generatorConfig.getRootPackageName())
            .setMapper(generatorConfig.getCustomDaoPackageName())
            .setXml(generatorConfig.getCustomMapperPackageName())// 自定义包路径
    );
  }

  // 自定义配置
  public void cfg(AutoGenerator mpg) {
    mpg.setCfg(
        // 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
        new InjectionConfig() {
          @Override
          public void initMap() {
            Map<String, Object> map = new HashMap<>();
            this.setMap(map);
          }
        })
        .setTemplate(new TemplateConfig().setEntity(null).setController(null)
            .setMapper("/templates/customDao.java.vm").setService(null).setServiceImpl(null)
            .setXml("/templates/customMapper.xml.vm"));
  }

  public void execute() {
    // 代码生成器
    AutoGenerator mpg = new AutoGenerator();
    // 全局配置
    golbalConfig(mpg);
    // 数据源配置
    dataSource(mpg);
    // 策略配置
    strategyConfig(mpg);
    // 包配置
    packageInfo(mpg);
    // 自定义配置
    cfg(mpg);
    // 执行生成
    mpg.execute();
  }
}
